/**
 * \file Process.h
 * \brief Process facilities
 * \author Corey Tabaka
 */

/*
   Copyright 2006 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include <ktypes.h>
#include <platform/PageTable.h>
#include <platform/PageMap.h>
#include <vm/AddressSpace.h>
#include <HandleMap.h>
#include <Message.h>
#include <Sync.h>

#include <Reference.h>

#ifndef __KERNEL_PROCESS_H__
#define __KERNEL_PROCESS_H__

class Process;
DEF_REF_TYPE(Process);

#include <Thread.h>

#define PROCESS_KERNEL_SPACE 	0x00200000
#define PROCESS_USER_SPACE		0x40100000
#define PROCESS_USER_SPACE_EXIT	0x40000000
#define PROCESS_LOW_SPACE		0x00000000

class Process {
	friend class Thread;
	friend class UserThread;
	friend class VM86Thread;
	
	protected:
		
	char name[256];
	
	RefProcess parent;
	RefProcess self;
	
	pid_t pid;	// process id
	uid_t uid;	// user id
	
	PageTable pageTable;
	PageMap *pageMap;
	
	HandleMap<RefThread> threads;
	
	handle_t pipeCount;
	HandleMap<RefMessagePipe> pipes;
	
	AddressSpace addressSpace;
	
	InterruptLock lock;
	InterruptLock asLock;
	
	Process(const char *name);
	Process(const char *name, PageMap &pageMap);
	Process(const char *name, RefProcess parent);
	
	static bool syscallHandler(regs_t *);
	
	public:
	
	static void initialize(void);
	
	static RefProcess getSystemProcess(void);
	static RefProcess getProcess(pid_t pid);
	static RefProcess createProcess(const char *name);
	static RefProcess getCurrentProcess(void);
	
	virtual ~Process(void);
	
	PageTable &getPageTable(void);
	PageMap &getPageMap(void);
	AddressSpace &getAddressSpace(void);
	
	const char *getName(void);
	
	pid_t getPid(void);
	
	handle_t createPipe(void);
	void destroyPipe(handle_t handle);
	RefMessagePipe getPipe(handle_t handle);
	
	bool loadBinary(const void *image, uint32 length, uint32 at,
		bool compressed=false);
	bool loadPeExe(const void *image, uint32 length, bool compressed=false);
	bool loadPeModule(const void *image, uint32 length, bool compressed=false);
};

#endif
